package com.hyacinth.repository.jpa;


import lombok.extern.slf4j.Slf4j;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.io.Serializable;
import java.util.*;


/**
 * 基础持久化类
 */
@Slf4j
public class BaseRepositoryImpl<T extends Serializable, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements BaseRepository<T, ID> {

    @PersistenceContext
    private EntityManager entityManager;


    public BaseRepositoryImpl(JpaEntityInformation<T, ID> entityInformation, EntityManager entityManager) {
        super(entityInformation, entityManager);
        this.entityManager = entityManager;
    }

    @Override
    public Optional<T> findByCode(Class<T> clazz,String code) {
        Query query = entityManager.createQuery("from " + clazz.getSimpleName() + " where code = '" + code + "'");
        Object object = query.getSingleResult();
        return Optional.of((T) object);
    }

    @Override
    public List queryIds(String sql) {
        List resultList = new ArrayList(0);
        try {
            Query nativeQuery = entityManager.createNativeQuery(sql);
            resultList = nativeQuery.getResultList();
        } catch (Exception e) {
            log.error("执行SQL查询异常！sql = {}", sql);
        }
        return resultList;
    }

    @Override
    public List queryObjByPaging(String hql, long page, long pageSize, Map<String, Object> paramMap) throws Exception {
        List dataList = new ArrayList();
        Query query = entityManager.createQuery(hql);
        Set<String> keySet = paramMap.keySet();
        for (String key : keySet) {
            Object object = paramMap.get(key);
            query.setParameter(key, object);
        }
        if (0 < pageSize) {
            query.setFirstResult((int) (page * pageSize));
            query.setMaxResults((int) pageSize);
            dataList = query.getResultList();
        }
        return dataList;
    }

    @Override
    public List queryObj(String hql, Map<String, Object> paramMap) throws Exception {
        Query query = entityManager.createQuery(hql);
        Set<String> keySet = paramMap.keySet();
        for (String key : keySet) {
            Object object = paramMap.get(key);
            query.setParameter(key, object);
        }
        return query.getResultList();
    }

    @Override
    public List queryObjs(String hql) throws Exception {
        Query query = entityManager.createQuery(hql);
        return query.getResultList();
    }

    @Override
    public Long queryObjCount(String hql, Map<String, Object> paramMap) throws Exception {
        Query query = entityManager.createQuery(hql);
        Set<String> keySet = paramMap.keySet();
        for (String key : keySet) {
            Object object = paramMap.get(key);
            query.setParameter(key, object);
        }
        List resultList = query.getResultList();
        return resultList != null && resultList.size() > 0 ? (Long) resultList.get(0) : 0;
    }

    @Transactional
    public void batchInsert(List listA) {
        int size = listA.size();
        for (int i = 0; i < size; i++) {
            entityManager.persist(listA.get(i));
            if (i % 1000 == 0) {
                entityManager.flush();
                entityManager.clear();
            }
        }
    }
}
